<template>
  <div>
    <video ref="videoElem" width="640" height="480" @play="drawAll" autoplay muted playsinline></video>
    <canvas ref="canvas" width="640" height="480" @mousedown="handleMouseDown" @mousemove="handleMouseMove" @mouseup="handleMouseUp" @dblclick="handleDoubleClick"></canvas>
    <button @click="setDrawMode('move')">Move Mode</button>
    <button @click="setDrawMode('point')">Draw Point</button>
    <button @click="setDrawMode('line')">Draw Line</button>
    <button @click="setDrawMode('rect')">Draw Rectangle</button>
    <button @click="printInfo">Print Info</button>
    <button @click="deleteSelected">Delete Selected</button>

  </div>
</template>

<script>
export default {
  data() {
    return {
      isDrawing: false,           // 标识当前是否在绘制
      startX: 0, startY: 0,      // 绘图起始坐标
      currentX: 0, currentY: 0,  // 当前鼠标位置
      drawings: [],               // 存储绘图数据
      drawMode: null,             // 当前的绘图模式 (例如：点、线、矩形)
      selectedDrawing: null,      // 当前选中的绘图对象
      diffX: 0, diffY: 0          // 鼠标与选中对象的坐标差异
    };
  },
  mounted() {
    // this.$refs.videoElem.src = "火眼金睛确定文件.mp4";
    this.loadInitialData();
  },
  methods: {
    drawAll() {
      const canvas = this.$refs.canvas;
      const ctx = canvas.getContext('2d');
      console.log( this.drawings)
      ctx.clearRect(0, 0, canvas.width, canvas.height);
      this.drawings.forEach(d => {
        ctx.strokeStyle = 'red';
        ctx.fillStyle = 'red';
        ctx.lineWidth = 1;
        if(d.type === 'point') {
          ctx.beginPath();
          ctx.arc(d.startX, d.startY, 4, 0, 2 * Math.PI);
          ctx.fill();
        } else if(d.type === 'line') {
          ctx.beginPath();
          ctx.moveTo(d.startX, d.startY);
          ctx.lineTo(d.endX, d.endY);
          ctx.stroke();
        } else if(d.type === 'rect') {
          ctx.beginPath();
          // 绘制一个矩形。为了确保无论从哪个方向开始绘制，矩形都可以正常显示，使用Math.min和Math.max来确定坐标
          ctx.rect(Math.min(d.startX, d.endX), Math.min(d.startY, d.endY), Math.abs(d.endX - d.startX), Math.abs(d.endY - d.startY));
          ctx.stroke();
        }
        // 如果当前绘制对象被选中，则以特殊方式高亮显示它
        if(d.selected) {
          ctx.strokeStyle = '#aaffaa';
          ctx.lineWidth = 2;
          if(d.type === 'point') {
            ctx.beginPath();
            ctx.arc(d.startX, d.startY, 4, 0, 2 * Math.PI);  // 绘制点，但这次只使用更宽的线条，而不填充
            ctx.stroke();
          } else if(d.type === 'line') {
            ctx.beginPath();
            ctx.moveTo(d.startX, d.startY);
            ctx.lineTo(d.endX, d.endY);
            ctx.stroke();
          } else if(d.type === 'rect') {
            ctx.beginPath();
            ctx.rect(Math.min(d.startX, d.endX) - 1, Math.min(d.startY, d.endY) - 1, Math.abs(d.endX - d.startX) + 2, Math.abs(d.endY - d.startY) + 2);
            ctx.stroke();
          }
          ctx.strokeStyle = 'red';
          ctx.lineWidth = 1;
        }
      });
    },

    handleMouseDown(event) {
      // offsetX相对于元素偏移量，clientX相对于浏览器可见的元素偏移量
      const x = event.offsetX;
      const y = event.offsetY;
      const that = this;
      // console.log("e:", event)
      // console.log("x:", x)
      // console.log("y:", y)
      // 判断当前的绘制模式是否为"move"（移动模式）
      if (this.drawMode === 'move') {
        // 在所有绘制对象中找到用户点击的那个对象
        this.selectedDrawing = this.drawings.find(d => {
          if (d.type === 'point') {
            // 对于点，计算点击位置与点的距离，如果小于等于5，则认为点击了该点
            return Math.sqrt((d.startX - x) ** 2 + (d.startY - y) ** 2) <= 5;
          } else if ( d.type === 'rect') {
            // 对于线和矩形，检查点击位置是否在它们的范围内
            return x >= Math.min(d.startX, d.endX) && x <= Math.max(d.startX, d.endX) && y >= Math.min(d.startY, d.endY) && y <= Math.max(d.startY, d.endY);
          }else if(d.type === 'line'){
            return that.pointOnLine(x,y,d.startX,d.startY,d.endX,d.endY,10);
          }
          return false;
        });

        // 如果找到了点击的绘制对象，记录点击位置与该对象起点的差值
        if (this.selectedDrawing) {
          this.diffX = x - this.selectedDrawing.startX;
          this.diffY = y - this.selectedDrawing.startY;
        }
      } else {
        // 如果不在移动模式，则记录开始绘制的起点，并设置isDrawing为true
        this.isDrawing = true;
        this.startX = x;
        this.startY = y;
      }
    },

    handleDoubleClick(event) {
      console.log("双击")
      const x = event.offsetX;
      const y = event.offsetY;
      // 在所有绘制对象中找到用户双击的那个对象
      const that = this ;
      const clickedDrawing = this.drawings.find(d => {
        if (d.type === 'point') {
          return Math.sqrt((d.startX - x) ** 2 + (d.startY - y) ** 2) <= 5;
        } else if ( d.type === 'rect') {
          return x >= Math.min(d.startX, d.endX) && x <= Math.max(d.startX, d.endX) && y >= Math.min(d.startY, d.endY) && y <= Math.max(d.startY, d.endY);
        }else if(d.type === 'line'){
          return that.pointOnLine(x,y,d.startX,d.startY,d.endX,d.endY,10);
        }
        return false;
      });
      // 如果找到了双击的绘制对象，则切换它的选中状态
      if (clickedDrawing) {
        this.form1 = clickedDrawing
        console.log("选择",this.form1)
        clickedDrawing.selected = !clickedDrawing.selected;
        // 重新绘制所有对象以反映变化
        this.drawAll();
      }
    },

    pointOnLine(px, py, x1, y1, x2, y2, tolerance) {
      let dx = x2 - x1;
      let dy = y2 - y1;
      let dist = Math.abs(dy * px - dx * py + x2 * y1 - y2 * x1) / Math.sqrt(dx * dx + dy * dy);
      return dist <= tolerance;
    },
checkBox(x,y,deltaX,deltaY,width,height){
  const sboundedX = Math.max(0,x);
  const sboundedY = Math.max(0, y);
  if(sboundedX==0||sboundedY==0){
    return false
  }
  if (this.selectedDrawing.type === 'line' || this.selectedDrawing.type === 'rect') {
    const eboundedX = Math.max(0, Math.min(this.selectedDrawing.endX + deltaX, width));
    const eboundedY = Math.max(0, Math.min(this.selectedDrawing.endY + deltaY, height));
    if (eboundedX==width||eboundedY==height){
      return false
    }
  }
  return true
},
    handleMouseMove(event) {
      const canvas = this.$refs.canvas;
      // 如果用户没有处于绘制状态，则不执行后面的代码
      if (!this.isDrawing) {
        // 如果用户选择了"移动"模式并选中了某个图形
        if (this.drawMode === 'move' && this.selectedDrawing) {
          const x = event.offsetX - this.diffX; // 计算新的x坐标
          const y = event.offsetY - this.diffY; // 计算新的y坐标

          const deltaX = x - this.selectedDrawing.startX; // x方向移动的距离
          const deltaY = y - this.selectedDrawing.startY; // y方向移动的距离

          // 更新选中图形的开始坐标

         let check = this.checkBox(x,y,deltaX,deltaY,canvas.width,canvas.height)
          console.log(check)
          if(check) {
            this.selectedDrawing.startX = x;
            this.selectedDrawing.startY = y;

            // 如果是线或矩形，同时更新结束坐标
            if (this.selectedDrawing.type === 'line' || this.selectedDrawing.type === 'rect') {


              this.selectedDrawing.endX += deltaX;
              this.selectedDrawing.endY += deltaY;
            }
          }
          this.drawAll(); // 重新绘制所有图形
        }
        return;
      }

      const ctx = canvas.getContext('2d');
      this.currentX = event.offsetX;
      this.currentY = event.offsetY;
      this.drawAll(); // 重新绘制所有图形, 以清除之前绘制的图形,否则重复轨迹
      // 根据绘制模式，动态绘制当前的图形
      if (this.drawMode === 'point') {
        ctx.beginPath();
        ctx.arc(this.startX, this.startY, 5, 0, 2 * Math.PI);
        ctx.fill();
      } else if (this.drawMode === 'line') {
        ctx.beginPath();
        ctx.moveTo(this.startX, this.startY);
        ctx.lineTo(this.currentX, this.currentY);
        ctx.stroke();
      } else if (this.drawMode === 'rect') {
        ctx.beginPath();
        ctx.rect(this.startX, this.startY, this.currentX - this.startX, this.currentY - this.startY);
        ctx.stroke();
      }
    },

    handleMouseUp(event) {
      this.isDrawing = false; // 结束绘制状态

      // 如果不是在"移动"模式
      if (this.drawMode !== 'move') {
        // 根据绘制模式，添加新的图形到drawings数组中
        if (this.drawMode === 'point') {
          this.drawings.push({
            type: 'point',
            startX: this.startX,
            startY: this.startY
          });
        } else if (this.drawMode === 'line') {
          this.drawings.push({
            type: 'line',
            startX: this.startX,
            startY: this.startY,
            endX: this.currentX,
            endY: this.currentY
          });
        } else if (this.drawMode === 'rect') {
          this.drawings.push({
            type: 'rect',
            startX: this.startX,
            startY: this.startY,
            endX: this.currentX,
            endY: this.currentY
          });
        }
        this.drawAll(); // 重新绘制所有图形
      }

      // 重置选中的图形和相关的坐标差值
      this.selectedDrawing = null;
      this.diffX = 0;
      this.diffY = 0;
    },

    printInfo() {
      console.log(this.drawings);
    },

    setDrawMode(mode) {
      this.drawMode = mode;
      this.isDrawing = false;
      this.selectedDrawing = null;
    },

    loadInitialData() {
      // 模拟数据
      this.drawings = [
        { type: 'point', startX: 100, startY: 100, selected: false,name:'点' },
        { type: 'line', startX: 150, startY: 150, endX: 300, endY: 300, selected: false,name:'线' },
        { type: 'rect', startX: 350, startY: 350, endX: 400, endY: 400, selected: false,name:'框' }
      ];
      this.drawAll();
    },

    deleteSelected() {
      console.log("deleted before:", this.drawings);
      this.drawings = this.drawings.filter(d => !d.selected);
      console.log("deleted after", this.drawings);
      this.drawAll();
    }
  },
};
</script>


<style scoped>
canvas, video {
  position: absolute;
  top: 100px;
  left: 50px;
}
canvas {
  border: greenyellow 1px solid;
  cursor: crosshair;
}
</style>

